#include "SDLEventFactory.h"
#include <SECore/Events/QuitEvent.h>
#include <SECore/Events/MouseEvent.h>
#include <SECore/Events/KeyBoardEvent.h>
#include <SECore/Events/Input.h>

#include <SEDebug/Log/Log.h>

namespace SEngine
{

    std::unordered_map<SDL_EventType, std::function<EventPtr(SDL_Event&)>> SDLEventFactory::s_eventTable{
        {
            SDL_QUIT,
            [](SDL_Event & event) {
                return std::make_shared<QuitEvent>();
            }
        },  
        {
            SDL_MOUSEBUTTONDOWN,
            [](SDL_Event & event) {
                auto e = std::make_shared<MousePressEvent>();
                e->SetXPos(event.button.x);
                e->SetYPos(event.button.y);
                e->SetButton((MouseButton)event.button.button);
                Input::GetInstance().SetMousePressed(e->GetButton(), true);
                return e;
            }
        },  
        {
            SDL_MOUSEBUTTONUP,
            [](SDL_Event & event) {
                auto e = std::make_shared<MouseReleaseEvent>();
                e->SetXPos(event.button.x);
                e->SetYPos(event.button.y);
                e->SetButton((MouseButton)event.button.button);
                Input::GetInstance().SetMousePressed(e->GetButton(), false);
                return e;
            }
        },  
        {
            SDL_MOUSEMOTION,
            [](SDL_Event & event) {
                auto e = std::make_shared<MouseMoveEvent>();
                e->SetXPos(event.button.x);
                e->SetYPos(event.button.y);
                e->SetButton((MouseButton)(event.button.button == 4 ? SE_RIGHT : event.button.button));
                return e;
            }
        },  
        {
            SDL_MOUSEWHEEL,
            [](SDL_Event & event) {
                Input::GetInstance().SetMouseWheelXY(event.wheel.x, event.wheel.y);
                return std::make_shared<MouseWheelEvent>(event.wheel.x, event.wheel.y);
            }
        },  
        {
            SDL_KEYDOWN,
            [](SDL_Event & event) {
                auto e = std::make_shared<KeyPressEvent>();
                e->SetKey(event.key.keysym.sym);
                Input::GetInstance().SetKeyPressed(e->GetKey(), true);
                return e;
            }
        },  
        {
            SDL_KEYUP,
            [](SDL_Event & event) {
                auto e = std::make_shared<KeyReleaseEvent>();
                e->SetKey(event.key.keysym.sym);
                Input::GetInstance().SetKeyPressed(e->GetKey(), false);
                return e;
            }
        },  
    };
    

    SDLEventFactory::SDLEventFactory(SDL_Event & event)
        : m_event(event)
    {

    }

    EventPtr SDLEventFactory::Create()
    {
        if (s_eventTable.find(static_cast<SDL_EventType>(m_event.type)) == s_eventTable.end()) {
            return nullptr;
        }
        return s_eventTable[static_cast<SDL_EventType>(m_event.type)](m_event);
    }

} // namespace SEngine
